﻿
// iTransDlg.h : 헤더 파일
//

#pragma once

#include <cmath>
#include "AddFileListCtrl.h"
#include "Sami2Srt.h"
#include "RewriteSrt.h"
#include "Redirect.h"
#include "MediaInfo.h"
#include "FixTtxt.h"
#include "Ass2Srt.h"
#include "Ttxt2Srt.h"
#include "FinishDlg.h"
#include "CompositeKorean.h"
#include "CreateLog.h"
#include "SmallUtilz.h"
#include "ChapterHelper.h"
#include "OptionDlg.h"

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);

// CiTransDlg 대화 상자
class CiTransDlg : public CDialog
{
// 생성입니다.
public:
	CiTransDlg(CWnd* pParent = NULL);	// 표준 생성자입니다.

// 대화 상자 데이터입니다.
	enum { IDD = IDD_ITRANS_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 지원입니다.


// 구현입니다.
protected:
	HICON m_hIcon;
	CRedirect *redir;
	CString csRootPath;
	CString csTempPath;
	CString csTempPath83;
	CString csSavePath;
	bool bOnConversion;
	unsigned char *fontsizes;
	BOOL bIsControlEnabled;
	CString csSystemPath;
	CCreateLog clog;
	BOOL bPersianBlueBox;
	bool bNightly;
	CString appVersionStr;
	CStringArray csaTempFiles;
	LPCTSTR lpLogFilename;
	CString csLogMsg;

	// 생성된 메시지 맵 함수
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

public:
	BOOL m_bKeepRotate;
	BOOL m_bMuxAC3;
	BOOL m_bBurnSubtitle;
	BOOL m_bCreateLog;
	BOOL m_bShutdown;
	int m_iIDevice;
	int m_iConversionMode;
	int m_iRotate;
	int m_iKeepTempFiles;
	CAddFileListCtrl m_clcFiles;
	CStatusBarCtrl	m_StatusBar;

	virtual BOOL PreTranslateMessage(MSG* pMsg);
	afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
	void initOptDlg(COptionDlg &optionDlg);
	BOOL OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult);
	void EnableControls(BOOL bEnabled);
	void DrawBoxRotate();
	void DrawBoxShutdown();
	void SetTBProgressValue(ULONGLONG progress, ULONGLONG max);
	void SetTBProgressState(TBPFLAG tbpFlags);
	void copyToOptionDialog(COptionDlg &optionDlg);
	void copyFromOptionDialog(COptionDlg &optionDlg);
	LPCTSTR GetThisPath();
	void LoadFromRegistry();
	void InitFont();
	void SetUIFont(HFONT &hFont, LOGFONT &lFont, TCHAR *tcFont, long lSize/*, BOOL bBold*/);
	bool getRegValBoolOrInt(HKEY hKey, TCHAR *name, void *var);
	bool getRegValCString(HKEY hKey, TCHAR *name, CString &var);
	BOOL bGetRegValueDWORD(HKEY hkey, TCHAR *tcName, DWORD &dwRet);
	TCHAR* GetRegValueTCHAR(HKEY hkey, TCHAR *tcName);
	void RunApp(LPCTSTR lpApp, LPCTSTR lpParam, CStringArray &csaAppsLong, bool writeLog = true, double *dMaxVolume = NULL);
	void RemoveTempFiles();
	void MakeLogFilename();
	void CreateLog();
	void WriteLog(LPCTSTR lpStr, LPCTSTR lpStr2=NULL, bool bWriteTime=true);
	void WriteOptionsToLog();
	void WriteHDDSizeToLog(LPCTSTR lpTarget);
	CString csGetShortName(LPCTSTR lpFilename);
	void printfuni2ansi(FILE *f, const TCHAR *tc);
	CString csCompositeKorean(LPCTSTR lpFilename);
	void AddTempList(CStringArray &csaTemp, CString cs);
	BOOL bGetMaxResolution(int iMachine, double dFPS);
	BOOL bConvertResolution(int iWidth, int iHeight);
	CString csGetLanguageID(LPCTSTR lp);
	void checkTempFile(CString &csTempFile);
	int iGetMaxVolume(LPCTSTR lpSrc, int streamorder, double * pdMaxDecibel);
	int iEncode2AAC(LPCTSTR lpSrc, bool bIsExternal, CMediaInfo &mediainfo, int iAudioPos, int &iDelay, int iCount, LPCTSTR lpCount , CString & csAAC);
	int iExtractAudio(int iInternalAudio, LPCTSTR lpCount, CString &csAudioOut, int &iAudioDelayOut, TCHAR *tcLangOut, int buffersize);
	CString csMakeValidPCM(LPCTSTR lpAudio, int iSamplingRate, int iBitDepth, int iChannels);
	BOOL bIsPCM(LPCTSTR lpFile, bool bMonoOrStereo = false);
	void makeNewSrtName(int subno, int trackno, CString &csNewSrt);
	CString Srt2Ttxt(CString csSrt);
	BOOL bIsFileEnglishText(LPCTSTR lpFilename, bool bCheckAmp=false);
	bool changeAssFontSize(LPCTSTR lpAss, unsigned char size);
	void encode2H264(CString csDst, int iPass, int iProfile2, LPCTSTR lpFPS, int iBitRate, int iRotate, LPCTSTR lpAssSub=NULL);
	TCHAR * tcGetElapsedTime(DWORD dwTimeElapsed, bool miliSec=false);
	CString csGetH264MaxLevel(int iWidth, int iHeight, CString csFPS);
	unsigned int uiGCD(unsigned int x, unsigned int y);
	void checkSourceFilesInFinal(CString &csMP4OptionFull);
	//void CopyFileDate(LPCTSTR lpSource, LPCTSTR lpTarget);
	void setFileDateFromCDate(LPCTSTR lpFile, CTime &ctime);
	int findSpace(CString &str);
	bool checkFolders();
	bool checkExternalApps();
	bool getExeNamesInPath(LPCTSTR lpToolExe, CStringArray &csaExe);
	int getExeNames(LPCTSTR lpToolName, BOOL bPathFirst, int iPathOrToolsOnly, CStringArray &csaExe);
	bool getFFMpegBuildDate(COleDateTime &cDate);
	bool existFFMpegFontsConf();
	void assign1stAndWriteLog(CString &csLong, CString &csShort, CStringArray &csa, LPCTSTR name);

	bool step1_prepareJob();
	bool step2_processSubtitle();
	bool step3_convertAudio();
	bool step4_convertChapter();
	int step5_convertVideo();
	int step6_muxVideo();

	// Statusbar Control
	BOOL CreateStatusBar();
	void SetStatusBarText(int iPos, TCHAR *tc);
	// end of Statusbar Control

	// Option 데이터. 이전에는 멤버변수였음
	BOOL	o_b4GBonly;
	int		o_iConversionProfile2;
	BOOL	o_bCheck30fps;
	BOOL	o_bKeepPrefixOnlyWhenNeeded;
	int		o_iPAR;
	BOOL	o_bDeinterlace;
	BOOL	o_bPathFirst;
	BOOL	o_bCopyOriginDate;
	BOOL	o_bIgnoreUTC;
	BOOL	o_bFfmpegThreads;
	int		o_uFfmpegThreads;
	BOOL	o_bBothAudio;
	BOOL	o_bForceReEncodeAAC;
	BOOL	o_bAudioOrder;
	int		o_iAudioOrder;
	int		o_iAudioBR;
	BOOL	o_bNormalizeAudio;
	double	o_dNormalizeAudioInDB;
	BOOL	o_bDontDownmixAudio;
	BOOL	o_bExtract2SRT;
	int		o_iFontSize;
	BOOL	o_bBothSubtitles;
	BOOL	o_bSrtLang;
	int		o_iSrtLang;
	BOOL	o_bDefaultLangA;
	int		o_iDefaultLangA;
	BOOL	o_bDefaultLangS;
	int		o_iDefaultLangS;
	BOOL	o_bUseSaveFolder;

	// 공유 및 여러가지 절약 목적으로 여기
	SYSTEM_INFO si;
	OSVERSIONINFOEX osvi;
	CString osVersionstr;
	// 새로 만듦
	CString sOsInfoStr;
	CString sMemInfoStr;
	bool bIsWindowsVistaOrGreater;
	void getOsMemInfos();

protected:
	// FFMpeg의 thread 옵션 역시 여러가지 목적으로 여기 위치
	TCHAR ffmpegThreadsTstr[14];

	CString csFFMpegLong;
	CString csNeroAACLong;
	CString csMP4BoxLong;
	CString csMediaInfoLong;
	CString	csShutdownLong;

	CString csFFMpeg;
	CString csNeroAAC;
	CString csMP4Box;
	CString csMediaInfo;
	CString csShutdown;

	// 메인 루프 안의 기능들을 별도 함수로 빼기 위해 여기 배치

	// step0. 작업준비 이전 단계
	int l_iSuccessCount;
	bool l_bForceVideoEncode;

	bool l_bBurnSubtitle;
	CString l_csToolsRoot;

	// step1. 작업준비
	
	CMediaInfo l_aacsinfo[MAXAUDSUBCOUNT];
	int l_i, l_iCount;
	DWORD l_dwTime, l_dwTimeTotal;
	BOOL l_bThreadStopped;
	CString l_csSizeStr;
	CMediaInfo l_mediainfo;
	int l_iExtLen;
	CString l_csSrc, l_csSrc83, l_csExt, l_csSrcNoExt;
	CString l_csCover;

	CStringArray l_csaAAC;			// AAC 오디오 파일명 목록
	CStringArray l_csaAACOption;	// AAC 오디오 옵션 목록
	CStringArray l_csaAC3;			// AC3 오디오 파일명 목록
	CStringArray l_csaAC3Option;	// AC3 오디오 옵션 목록
	bool l_b1stAACisExternal;
	bool l_b1stAC3isExternal;
	int l_iAACDelay[MAXAUDSUBCOUNT];
	int l_iAC3Delay[MAXAUDSUBCOUNT];
	CString l_csExtAudioFilename;

	CString l_csFileInfo;
	double l_dFps;
	int l_iBitRate;
	int l_iWidthMax, l_iHeightMax, l_iWidthNew, l_iHeightNew;

	bool l_bUseExternalAudio;
	bool l_bUseInternalAudio;
	CString l_csExtAudioLang;
	CStringArray l_csaSubtitles;
	int l_iInternalAudio, l_iInternalValue;
	bool l_bAllAudio;
	int l_iExtAudioDelay;

	// step2. 자막처리
	CString l_csSubToBurn;
	CStringArray l_csaSrtTtxts;
	int l_iSubExt;		// 0: 자막 없음, 1: SMI 소스, 2: SRT 소스, 3: ASS 소스, 4: SSA 소스, 5: TTXT 소스
	bool l_bSubInt;

	// step3. 오디오 변환
	CString l_csDst, l_csDstSrtHeader;
	CString l_csOutPath;
	CString l_csDstTemp;
	int l_iVSyncAdjust, l_iASyncAdjust, l_iVideoDelay;

	CStringArray l_csaTtxts;
	CString l_csSubOption;

	// step4. 챕터 변환
	CString l_csChapterSrt;

	// step5. 비디오 변환
	CString l_csVideoOption, l_csVideoDelay, l_csPAR, l_csMP4OptionFull;

	static const int ciSTATUSBAR_HEIGHT;
	static const int ciCOLUMN_FILENAME;
	static const int ciCOLUMN_PATHNAME;
	static const int ciCOLUMN_EXTAUDIO;
	static const int ciCOLUMN_EXTSUBTL;
	static const int ciCOLUMN_EXTCOVER;
	static const int ciCOLUMN_EXTCHAPT;
	static const int ciCOLUMN_RESULTMS;

public:
	afx_msg void OnClickedButtonDesig();
	afx_msg void OnClickedButtonOption();
	afx_msg void OnClickedButtonDelete();
	afx_msg void OnClickedButtonDeleteAll();
	afx_msg void OnClickedButtonRun();
	afx_msg void OnClickedButtonStop();
	afx_msg void OnClickedCheckShutdown();
	afx_msg void OnSelchangeConversionMode();
	afx_msg void OnSelchangeComboMachine();
	afx_msg void OnSelchangeComboRotate();
	afx_msg void OnClickListFiles(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnKeydownListFiles(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnTimer(UINT_PTR nIDEvent);

protected:
	inline int isdigit_char(char c) { return __isascii(c) && isdigit(c); }
public:
	void append_l_csFileInfo_AudSubChinfo();
	bool isAudioExtractable(CMediaInfo & mediainfo, int iAudioPos);
	void addAudioFilenameAndOption(CStringArray &csaAudioFilename, CStringArray &csaAudioOption, int *iDelay, LPCTSTR lpFilename, LPCTSTR lpLang, int newdelay, CString *pcsTitle=NULL);
	void drawActiveProgress(int iStep, int iAudioPos);
	void modalAbout(void);
};
